import traceback, time, datetime
from copy import copy
from flask_login import UserMixin as LoginMixin
from werkzeug.security import generate_password_hash, check_password_hash
from flask_security import UserMixin, RoleMixin
from flask_security.utils import hash_password, verify_password
from utils.mongoengine import Document, fields
from utils.decorators import cached_property


class BothUserMixin(UserMixin, LoginMixin):
    pass


class User(Document, BothUserMixin):
    _model_desc_ = '用户'
    _dynamic = True
    name = fields.StringField(max_length=64)
    cname = fields.StringField(max_length=64)
    email = fields.StringField(max_length=120, unique=True)
    phone = fields.StringField(help_text="手机")
    password = fields.StringField(max_length=64, help_text='MD5加密存储')
    _roles = fields.ListField(fields.StringField(), help_text='role表的Key')
    # type = fields.StringField()
    active = fields.BooleanField(default=True)
    status = fields.StringField()
    casbin_unified_id_mark = 'email'  # casbin统一鉴别标志
    meta = {'strict': True}

    def __str__(self):
        return self.name

    def check_password_hash(self, password):
        return verify_password(password, self.password)

    def reset_password(self, password='invest1234'):
        self.password = hash_password(password)

    @cached_property
    def roles(self):
        from ..models import Role
        return list(Role.objects(key__in=self._roles))

    @cached_property
    def permissions(self):
        from ..models import Permission
        e = [r._permissions for r in self.roles]
        permission_ids = set([y for x in e for y in x])
        return Permission.objects(id__in=list(permission_ids))

    def add_role(self, role):
        pass

    def set_roles(self, roles):
        from app.user.models import Role
        roles = Role.objects(key__in=roles)
        self._roles = [str(role.key) for role in roles]
        self.save()
        dom = self.enterprise_id
        from utils.perm import e, get_casbin_id, reset_enforcer
        ori_roles = e.get_roles_for_user_in_domain(get_casbin_id(self), dom)
        role_list = [r.key for r in roles]
        for r in (set(ori_roles) - (set(ori_roles) & set(role_list))):
            e.delete_roles_for_user_in_domain(get_casbin_id(self), r, dom)
        for r in (set(role_list) - (set(ori_roles) & set(role_list))):
            e.add_role_for_user_in_domain(get_casbin_id(self), r, dom)
        reset_enforcer()

